﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cash.Model;
using CashCommon;
using CashResource;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;


namespace CashConnect
{
    class CashRegisterGate : ICashRegisterGate
    {
        public static CashRegisterGate Instance
        {
            get { return new CashRegisterGate(); }
        }
        public void RemoveById(int[] cashRegisterIds)
        {
            WFSql.DB.StartTransaction();
            try
            {
                SqlWork.SqlDeleteSimple("DELETE FROM dbo.FD_Suek_Cash_Register WHERE LINK = @LINK", cashRegisterIds, "LINK");
                WFSql.DB.Commit();
            }
            catch
            {
                WFSql.DB.Rollback();
                throw;
            }
        }
        public void ApplyToDb(CashRegister cashRegister)
        {
            RegisterInsert(cashRegister);
        }
        private void RegisterInsert(CashRegister cashRegister)
        {
            string sql =
                " INSERT INTO dbo.FD_Suek_Cash_Register (C_Name,D_Date,F_Division,F_Employers,F_Subscr,N_Amount,N_Code,N_Tax,C_Foundation,F_Sale_Categories,F_Sale_Items, N_State, F_Suek_Cash, N_Releaze)" +
                " OUTPUT INSERTED.LINK VALUES (@C_Name,@D_Date,@F_Division,@F_Employers,@F_Subscr,@N_Amount,@N_Code,@N_Tax,@C_Foundation,@F_Sale_Categories,@F_Sale_Items, 1, @F_Suek_Cash, @N_Releaze)";
            
            SqlCommand cmd = new SqlCommand(sql, WFSql.DB.SqlConnection, WFSql.DB.SqlTransaction);
            cmd.CommandType = CommandType.Text;

            WFSql.DB.AddInParameter("C_Name", SqlDbType.VarChar, DriverText.DriverRegisterName, cmd, false);
            WFSql.DB.AddInParameter("D_Date", SqlDbType.DateTime, cashRegister.DatePrint, cmd, false);
            WFSql.DB.AddInParameter("F_Division", SqlDbType.Int, cashRegister.F_Division, cmd, false);
            WFSql.DB.AddInParameter("F_Employers", SqlDbType.VarChar, cashRegister.CashEmployer.LINK, cmd, false);
            WFSql.DB.AddInParameter("F_Subscr", SqlDbType.Int, cashRegister.F_Subscr, cmd, false);
            WFSql.DB.AddInParameter("N_Amount", SqlDbType.Money, cashRegister.Amount, cmd, false);
            WFSql.DB.AddInParameter("N_Code", SqlDbType.Int, cashRegister.Number, cmd, false);
            WFSql.DB.AddInParameter("N_Tax", SqlDbType.Int, cashRegister.N_Tax, cmd, false);
            WFSql.DB.AddInParameter("C_Foundation", SqlDbType.VarChar, cashRegister.C_Foundation, cmd, false);
            WFSql.DB.AddInParameter("F_Sale_Categories", SqlDbType.VarChar, cashRegister.F_Sale_Categories, cmd, false);
            WFSql.DB.AddInParameter("F_Sale_Items", SqlDbType.VarChar, cashRegister.F_Sale_Items, cmd, false);
            WFSql.DB.AddInParameter("F_Suek_Cash", SqlDbType.BigInt, cashRegister.CashAccount.LINK, cmd, false);
            WFSql.DB.AddInParameter("N_Releaze", SqlDbType.TinyInt, cashRegister.N_Releaze, cmd, false);

            int registerID = 0;
            using (SqlDataReader sdr = cmd.ExecuteReader())
            {
                if (sdr.Read())
                    registerID = Convert.ToInt32(sdr["LINK"], CultureInfo.InvariantCulture);
            }

            cashRegister = CashRegister.Instant(registerID);

        }
        public void RefreshFromDb(CashRegister cashRegister)
        {
            String sql =
                " SELECT AbonentCode,AbonentName,N_State,C_Name,D_Date,DivisionName,EmployerName,F_Division,F_Subscr,Doc_Number,Sale_Categories_Name, F_Suek_Cash, SvDivisionName," +
                " Sale_Items_Name,LINK,N_Amount,N_Code,NMB,N_Tax,C_Foundation,S_Create_Date,F_Sale_Categories,F_Sale_Items,N_Releaze FROM dbo.V_FD_Suek_Cash_Register WHERE LINK = @LINK";

            SqlCommand cmd = new SqlCommand(sql, WFSql.DB.SqlConnection, WFSql.DB.SqlTransaction);
            cmd.Transaction = WFSql.DB.SqlTransaction;
            WFSql.DB.AddInParameter("LINK", SqlDbType.BigInt, cashRegister.ID, cmd, false);

            using (SqlDataReader sdr = cmd.ExecuteReader())
            {
                if (sdr.Read())
                {
                    cashRegister.AbonentCode = sdr["AbonentCode"].ToString();
                    cashRegister.AbonentName = sdr["AbonentName"].ToString();
                    cashRegister.Amount = Convert.ToDouble(sdr["N_Amount"], CultureInfo.InvariantCulture);
                    cashRegister.DatePrint = Convert.ToDateTime(sdr["D_Date"], CultureInfo.InvariantCulture);
                    cashRegister.CreatedEmployer = sdr["EmployerName"].ToString();
                    cashRegister.F_Division = Convert.ToInt32(sdr["F_Division"], CultureInfo.InvariantCulture);
                    cashRegister.IsPrinted = Convert.ToBoolean(sdr["N_State"], CultureInfo.InvariantCulture);
                    cashRegister.Name = sdr["C_Name"].ToString();
                    cashRegister.Number = Convert.ToInt32(sdr["N_Code"], CultureInfo.InvariantCulture);
                    cashRegister.N_Tax = Convert.ToInt32(sdr["N_Tax"], CultureInfo.InvariantCulture);
                    cashRegister.C_Foundation = sdr["C_Foundation"].ToString();
                    cashRegister.OrderNumber = sdr["Doc_Number"].ToString();
                    cashRegister.Sale_Categories_Name = sdr["Sale_Categories_Name"].ToString();
                    cashRegister.Sale_Items_Name = sdr["Sale_Items_Name"].ToString();
                    cashRegister.F_Subscr = Convert.ToInt32(sdr["F_Subscr"], CultureInfo.InvariantCulture);
                    cashRegister.F_Sale_Categories = Convert.ToInt32(sdr["F_Sale_Categories"], CultureInfo.InvariantCulture);
                    cashRegister.F_Sale_Items = Convert.ToInt32(sdr["F_Sale_Items"], CultureInfo.InvariantCulture);
                    cashRegister.CashAccount = CashAccount.Instant(Convert.ToInt32(sdr["F_Suek_Cash"], CultureInfo.InvariantCulture));
                    cashRegister.N_Releaze = Convert.ToInt32(sdr["N_Releaze"], CultureInfo.InvariantCulture);
                }
            }
        }
        public void PrintCheck(CashRegister cashRegister)
        {
            try
            {
                WFSql.DB.StartTransaction();

                IPrintDoc printDoc = Builder.PrintDoc(cashRegister);
                printDoc.Init();

                // Добавление записи в базу данных
                RegisterInsert(cashRegister);

                // Печать чека
                if (Cash.Properties.Settings.Default.WithoutKKM == 0)
                    printDoc.PrintCash(cashRegister);

                // Печать копии чека
                if (Cash.Properties.Settings.Default.PrintCheck == 1)
                    printDoc.PrintCopyCash(cashRegister);

                // Чек изменяет состояние на распечатанный
                if (cashRegister.CashAccount != null)
                    cashRegister.CashAccount.SetStatePaied(cashRegister.DatePrint);

                WFSql.DB.Commit();
            }
            catch (Exception err)
            {
                WFSql.DB.Rollback();
                throw new ECash(MessageType.AllertLog, CommonError.CashRegisterPrintError, err);
            }

        }
        public PostResult PostDocuments(DateTime dateTime, int fDivision)
        {
            WFSql.DB.StartTransaction();
            SqlParameter prmRes;
            SqlParameter sumRes;

            try
            {
                SqlCommand cmd = new SqlCommand("dbo.UI_SUEK_Pay", WFSql.DB.SqlConnection, WFSql.DB.SqlTransaction);
                cmd.CommandType = CommandType.StoredProcedure;
                WFSql.DB.AddInParameter ("F_Division", SqlDbType.TinyInt, fDivision, cmd, false);
                WFSql.DB.AddInParameter("Date_Doc", SqlDbType.VarChar, dateTime.ToString("yyyyMMdd"), cmd, false);
                prmRes = WFSql.DB.AddOutParameter("@COUNT", SqlDbType.Int, cmd);
                sumRes = WFSql.DB.AddOutParameter("@Sum", SqlDbType.Float, cmd);
                cmd.ExecuteNonQuery();

                WFSql.DB.Commit();
            }
            catch
            {
                WFSql.DB.Rollback();
                throw;
            }
            
            PostResult postResult = new PostResult();
            postResult.Count = Convert.ToInt32(prmRes.Value, CultureInfo.InvariantCulture);
            postResult.Sum = Convert.ToDouble(sumRes.Value, CultureInfo.InvariantCulture);
            postResult.DatePost = dateTime;

            return postResult;
        }
        public CashCommon.Sequence GetSequence(CashCommon.SqlSwitch swth)
        {
            Sequence.SqlGate = Builder.SqlGate;
            Sequence sequence = new Sequence();
            sequence.Sql =
                " SELECT NMB, LINK, F_Division, AbonentCode, AbonentName, N_State, C_Name, D_Date, DivisionName, EmployerName, F_Subscr," +
                " N_Amount, N_Code, N_Tax, C_Foundation, D_Date_Search, C_CorrAccount FROM dbo.V_FD_Suek_Cash_Register WHERE 1 = 1";
            sequence.Fields = new List<List<string>>() {
                new List<string>() {"NMB", FieldsName.NMB}, 
				new List<string>() {"LINK", FieldsName.LINK},
				new List<string>() {"F_DIVISION", FieldsName.F_Division},
                new List<string>() {"ABONENTCODE", FieldsName.CashAccountCodeName},
                new List<string>() {"ABONENTNAME", FieldsName.CashAccountSubscrName},
                new List<string>() {"F_SUBSCR", FieldsName.CashAccountCodeName},
                new List<string>() {"N_STATE", ""},
                new List<string>() {"C_NAME", FieldsName.CashRegisterDocName},
                new List<string>() {"D_DATE", FieldsName.CashAccountDivisionDate},
                new List<string>() {"DIVISIONNAME", FieldsName.CashAccountDivisionName},
                new List<string>() {"EMPLOYERNAME", FieldsName.CashAccountEmploerName},
                new List<string>() {"F_SUBSCR", FieldsName.CashAccountSubscrIdName},
                new List<string>() {"N_AMOUNT", FieldsName.CashAccountMoney},
                new List<string>() {"N_CODE", FieldsName.CashRegisterNumberName},
                new List<string>() {"N_TAX", FieldsName.N_Tax},
                new List<string>() {"C_FOUNDATION", FieldsName.CashRegisterFoundationName},
                new List<string>() {"C_CORRACCOUNT", FieldsName.CashRegisterCorrAccount},
                new List<string>() {"D_DATE_SEARCH", FieldsName.CashRegisterDate112Name}
            };

            if (swth != null)
                sequence.SqlSwitch.Condition = swth.Condition.Where(i => sequence.Fields.Select(res => res[0]).Contains(i.Name.ToUpper())).ToList();

            sequence.Index = 0;
            sequence.RecordCount = Adjustment.Default.CountRecordCash;

            return sequence;
        }
    }
}
